home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / fluid / fluid.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-04-18  |  11.3 KB  |  433 lines

  1. //
  2. // "$Id: fluid.cxx,v 1.15.2.1 1999/04/18 23:43:42 mike Exp $"
  3. //
  4. // FLUID main entry for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. const char *copyright =
  27. "The FLTK user interface designer version 1.0\n"
  28. "Copyright 1998-1999 by Bill Spitzak and others.\n"
  29. "\n"
  30. "This library is free software; you can redistribute it and/or "
  31. "modify it under the terms of the GNU Library General Public "
  32. "License as published by the Free Software Foundation; either "
  33. "version 2 of the License, or (at your option) any later version.\n"
  34. "\n"
  35. "This library is distributed in the hope that it will be useful, "
  36. "but WITHOUT ANY WARRANTY; without even the implied warranty of "
  37. "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
  38. "See the GNU Library General Public License for more details.\n"
  39. "\n"
  40. "You should have received a copy of the GNU Library General Public "
  41. "License along with this library; if not, write to the Free Software "
  42. "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
  43. "USA.\n"
  44. "\n"
  45. "Please report bugs to fltk-bugs@easysw.com.";
  46.  
  47. #include <FL/Fl.H>
  48. #include <FL/Fl_Double_Window.H>
  49. #include <FL/Fl_Box.H>
  50. #include <FL/Fl_Button.H>
  51. #include <FL/Fl_Hold_Browser.H>
  52. #include <FL/Fl_Menu_Bar.H>
  53. #include <FL/Fl_Input.H>
  54. #include <FL/fl_ask.H>
  55. #include <FL/fl_draw.H>
  56. #include <FL/fl_file_chooser.H>
  57. #include <FL/fl_message.H>
  58. #include <FL/filename.H>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <ctype.h>
  63. #include <errno.h>
  64.  
  65. #if defined(WIN32) && !defined(CYGNUS)
  66. # include <direct.h>
  67. #else
  68. # include <unistd.h>
  69. #endif
  70.  
  71. #include "about_panel.h"
  72.  
  73. #include "Fl_Type.h"
  74.  
  75. ////////////////////////////////////////////////////////////////
  76.  
  77. void nyi(Fl_Widget *,void *) {
  78.     fl_message("That's not yet implemented, sorry");
  79. }
  80.  
  81. static const char *filename;
  82. void set_filename(const char *c);
  83. int modflag;
  84.  
  85. static char* pwd;
  86. static char in_source_dir;
  87. void goto_source_dir() {
  88.   if (in_source_dir) return;
  89.   if (!filename || !*filename) return;
  90.   const char *p = filename_name(filename);
  91.   if (p <= filename) return; // it is in the current directory
  92.   char buffer[1024];
  93.   strcpy(buffer,filename);
  94.   int n = p-filename; if (n>1) n--; buffer[n] = 0;
  95.   if (!pwd) {
  96.     pwd = getcwd(0,1024);
  97.     if (!pwd) {fprintf(stderr,"getwd : %s\n",strerror(errno)); return;}
  98.   }
  99.   if (chdir(buffer)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
  100.                 buffer, strerror(errno)); return;}
  101.   in_source_dir = 1;
  102. }
  103.  
  104. void leave_source_dir() {
  105.   if (!in_source_dir) return;
  106.   if (chdir(pwd)<0) {fprintf(stderr, "Can't chdir to %s : %s\n",
  107.                  pwd, strerror(errno));}
  108.   in_source_dir = 0;
  109. }
  110.   
  111. Fl_Window *main_window;
  112.  
  113. void save_cb(Fl_Widget *, void *v) {
  114.   const char *c = filename;
  115.   if (v || !c || !*c) {
  116.     if (!(c=fl_file_chooser("Save to:", "*.f[ld]", c))) return;
  117.     set_filename(c);
  118.   }
  119.   if (!write_file(c)) {
  120.     fl_message("Error writing %s: %s", c, strerror(errno));
  121.     return;
  122.   }
  123.   modflag = 0;
  124. }
  125.  
  126. void exit_cb(Fl_Widget *,void *) {
  127.   if (modflag)
  128.     switch (fl_choice("Save changes before exiting?", "Cancel", "No", "Yes"))
  129.     {
  130.       case 0 : /* Cancel */
  131.           return;
  132.       case 2 : /* Yes */
  133.           save_cb(NULL, NULL);
  134.       if (modflag) return;    // Didn't save!
  135.     }
  136.  
  137.   exit(0);
  138. }
  139.  
  140. void open_cb(Fl_Widget *, void *v) {
  141.   if (!v && modflag && !fl_ask("Discard changes?")) return;
  142.   const char *c;
  143.   if (!(c = fl_file_chooser("Open:", "*.f[ld]", filename))) return;
  144.   if (!read_file(c, v!=0)) {
  145.     fl_message("Can't read %s: %s", c, strerror(errno));
  146.     return;
  147.   }
  148.   if (!v) {set_filename(c); modflag = 0;}
  149.   else modflag = 1;
  150. }
  151.  
  152. void new_cb(Fl_Widget *, void *v) {
  153.   if (!v && modflag && !fl_ask("Discard changes?")) return;
  154.   const char *c;
  155.   if (!(c = fl_file_chooser("New:", "*.f[ld]", 0))) return;
  156.   delete_all();
  157.   set_filename(c);
  158.   modflag = 0;
  159. }
  160.  
  161. static int compile_only = 0;
  162. int header_file_set = 0;
  163. int code_file_set = 0;
  164. const char* header_file_name = ".h";
  165. const char* code_file_name = ".cxx";
  166.  
  167. void write_cb(Fl_Widget *, void *) {
  168.   if (!filename) {
  169.     save_cb(0,0);
  170.     if (!filename) return;
  171.   }
  172.   char cname[1024];
  173.   char hname[1024];
  174.   if (*code_file_name == '.') {
  175.     strcpy(cname,filename_name(filename));
  176.     filename_setext(cname, code_file_name);
  177.   } else {
  178.     strcpy(cname, code_file_name);
  179.   }
  180.   if (*header_file_name == '.') {
  181.     strcpy(hname,filename_name(filename));
  182.     filename_setext(hname, header_file_name);
  183.   } else {
  184.     strcpy(hname, header_file_name);
  185.   }
  186.   if (!compile_only) goto_source_dir();
  187.   int x = write_code(cname,hname);
  188.   if (!compile_only) leave_source_dir();
  189.   strcat(cname, "/"); strcat(cname,header_file_name);
  190.   if (compile_only) {
  191.     if (!x) {fprintf(stderr,"%s : %s\n",cname,strerror(errno)); exit(1);}
  192.   } else {
  193.     if (!x) {
  194.       fl_message("Can't write %s: %s", cname, strerror(errno));
  195.     } else {
  196.       fl_message("Wrote %s", cname, 0);
  197.     }
  198.   }
  199. }
  200.  
  201. void openwidget_cb(Fl_Widget *, void *) {
  202.   if (!Fl_Type::current) {
  203.     fl_message("Please select a widget");
  204.     return;
  205.   }
  206.   Fl_Type::current->open();
  207. }
  208.  
  209. void toggle_overlays(Fl_Widget *,void *);
  210.  
  211. void select_all_cb(Fl_Widget *,void *);
  212.  
  213. void group_cb(Fl_Widget *, void *);
  214.  
  215. void ungroup_cb(Fl_Widget *, void *);
  216.  
  217. extern int pasteoffset;
  218. static int ipasteoffset;
  219.  
  220. static char* cutfname() {
  221. #ifdef WIN32
  222.   return "\\.fluid_cut_buffer";
  223. #else
  224.   static char name[256] = "~/.fluid_cut_buffer";
  225.   static char beenhere;
  226.   if (!beenhere) {beenhere = 1; filename_expand(name,name);}
  227.   return name;
  228. #endif
  229. }
  230.  
  231. void copy_cb(Fl_Widget*, void*) {
  232.   if (!Fl_Type::current) return;
  233.   ipasteoffset = 10;
  234.   if (!write_file(cutfname(),1)) {
  235.     fl_message("Can't write %s: %s", cutfname(), strerror(errno));
  236.     return;
  237.   }
  238. }
  239.  
  240. extern void select_only(Fl_Type *);
  241. void cut_cb(Fl_Widget *, void *) {
  242.   if (!Fl_Type::current) return;
  243.   ipasteoffset = 0;
  244.   Fl_Type *p = Fl_Type::current->parent;
  245.   while (p && p->selected) p = p->parent;
  246.   if (!write_file(cutfname(),1)) {
  247.     fl_message("Can't write %s: %s", cutfname(), strerror(errno));
  248.     return;
  249.   }
  250.   delete_all(1);
  251.   if (p) select_only(p);
  252. }
  253.  
  254. extern int force_parent, gridx, gridy;
  255.  
  256. void paste_cb(Fl_Widget*, void*) {
  257.   if (ipasteoffset) force_parent = 1;
  258.   pasteoffset = ipasteoffset;
  259.   if (gridx>1) pasteoffset = ((pasteoffset-1)/gridx+1)*gridx;
  260.   if (gridy>1) pasteoffset = ((pasteoffset-1)/gridy+1)*gridy;
  261.   if (!read_file(cutfname(), 1)) {
  262.     fl_message("Can't read %s: %s", cutfname(), strerror(errno));
  263.   }
  264.   pasteoffset = 0;
  265.   ipasteoffset += 10;
  266.   force_parent = 0;
  267. }
  268.  
  269. void earlier_cb(Fl_Widget*,void*);
  270.  
  271. void later_cb(Fl_Widget*,void*);
  272.  
  273. Fl_Type *sort(Fl_Type *parent);
  274.  
  275. static void sort_cb(Fl_Widget *,void *) {
  276.   sort((Fl_Type*)0);
  277. }
  278.  
  279. void show_alignment_cb(Fl_Widget *, void *);
  280.  
  281. void about_cb(Fl_Widget *, void *) {
  282.   if (!about_panel) make_about_panel(copyright);
  283.   copyright_box->hide();
  284.   display_group->show();
  285.   about_panel->show();
  286. }
  287.  
  288. ////////////////////////////////////////////////////////////////
  289.  
  290. extern Fl_Menu_Item New_Menu[];
  291.  
  292. Fl_Menu_Item Main_Menu[] = {
  293. {"&File",0,0,0,FL_SUBMENU},
  294.   {"New", 0, new_cb, 0},
  295.   {"Open...", FL_ALT+'o', open_cb, 0},
  296.   {"Save", FL_ALT+'s', save_cb, 0},
  297.   {"Save As...", FL_ALT+'S', save_cb, (void*)1},
  298.   {"Merge...", FL_ALT+'i', open_cb, (void*)1, FL_MENU_DIVIDER},
  299.   {"Write code", FL_ALT+'C', write_cb, 0},
  300.   {"Quit", FL_ALT+'q', exit_cb},
  301.   {0},
  302. {"&Edit",0,0,0,FL_SUBMENU},
  303.   {"Undo", FL_ALT+'z', nyi},
  304.   {"Cut", FL_ALT+'x', cut_cb},
  305.   {"Copy", FL_ALT+'c', copy_cb},
  306.   {"Paste", FL_ALT+'v', paste_cb},
  307.   {"Select All", FL_ALT+'a', select_all_cb, 0, FL_MENU_DIVIDER},
  308.   {"Open...", FL_F+1, openwidget_cb},
  309.   {"Sort",0,sort_cb},
  310.   {"Earlier", FL_F+2, earlier_cb},
  311.   {"Later", FL_F+3, later_cb},
  312. //{"Show", FL_F+5, show_cb},
  313. //{"Hide", FL_F+6, hide_cb},
  314.   {"Group", FL_F+7, group_cb},
  315.   {"Ungroup", FL_F+8, ungroup_cb,0, FL_MENU_DIVIDER},
  316. //{"Deactivate", 0, nyi},
  317. //{"Activate", 0, nyi, 0, FL_MENU_DIVIDER},
  318.   {"Overlays on/off",FL_ALT+'O',toggle_overlays},
  319.   {"Preferences",FL_ALT+'p',show_alignment_cb},
  320.   {0},
  321. {"&New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER},
  322. {"&Help",0,0,0,FL_SUBMENU},
  323.   {"About fluid",0,about_cb},
  324. //{"Manual",0,nyi},
  325.   {0},
  326. {0}};
  327.  
  328. #define BROWSERWIDTH 300
  329. #define BROWSERHEIGHT 500
  330. #define WINWIDTH 300
  331. #define MENUHEIGHT 30
  332. #define WINHEIGHT (BROWSERHEIGHT+MENUHEIGHT)
  333.  
  334. extern void fill_in_New_Menu();
  335.  
  336. void make_main_window() {
  337.   if (!main_window) {
  338.     Fl_Widget *o;
  339.     main_window = new Fl_Double_Window(WINWIDTH,WINHEIGHT,"fluid");
  340.     main_window->box(FL_NO_BOX);
  341.     o = make_widget_browser(0,MENUHEIGHT,BROWSERWIDTH,BROWSERHEIGHT);
  342.     o->box(FL_FLAT_BOX);
  343.     main_window->resizable(o);
  344.     Fl_Menu_Bar *m = new Fl_Menu_Bar(0,0,BROWSERWIDTH,MENUHEIGHT);
  345.     m->menu(Main_Menu);
  346.     m->global();
  347.     fill_in_New_Menu();
  348.     main_window->end();
  349.   }
  350. }
  351.  
  352. void set_filename(const char *c) {
  353.   if (filename) free((void *)filename);
  354.   filename = strdup(c);
  355.   if (main_window) main_window->label(filename);
  356. }
  357.  
  358. ////////////////////////////////////////////////////////////////
  359.  
  360. static int arg(int argc, char** argv, int& i) {
  361.   if (argv[i][1] == 'c' && !argv[i][2]) {compile_only = 1; i++; return 1;}
  362.   if (argv[i][1] == 'o' && !argv[i][2] && i+1 < argc) {
  363.     code_file_name = argv[i+1];
  364.     code_file_set  = 1;
  365.     i += 2;
  366.     return 2;
  367.   }
  368.   if (argv[i][1] == 'h' && !argv[i][2]) {
  369.     header_file_name = argv[i+1];
  370.     header_file_set  = 1;
  371.     i += 2;
  372.     return 2;
  373.   }
  374.   return 0;
  375. }
  376.  
  377. #ifndef WIN32
  378.  
  379. #include <signal.h>
  380. #ifdef _sigargs
  381. #define SIGARG _sigargs
  382. #else
  383. #ifdef __sigargs
  384. #define SIGARG __sigargs
  385. #else
  386. #define SIGARG int // you may need to fix this for older systems
  387. #endif
  388. #endif
  389.  
  390. static void sigint(SIGARG) {
  391.   signal(SIGINT,sigint);
  392.   exit_cb(0,0);
  393. }
  394.  
  395. #endif
  396.  
  397. int main(int argc,char **argv) {
  398.   int i = 1;
  399.   if (!Fl::args(argc,argv,i,arg) || i < argc-1) {
  400.     fprintf(stderr,"usage: %s <switches> name.fl\n"
  401. " -c : write .cxx and .h and exit\n"
  402. " -o <name> : .cxx output filename, or extension if <name> starts with '.'\n"
  403. " -h <name> : .h output filename, or extension if <name> starts with '.'\n"
  404. "%s\n", argv[0], Fl::help);
  405.     return 1;
  406.   }
  407.   const char *c = argv[i];
  408.   make_main_window();
  409.   if (c) set_filename(c);
  410.   if (!compile_only) {
  411.     Fl::visual((Fl_Mode)(FL_DOUBLE|FL_INDEX));
  412.     main_window->callback(exit_cb);
  413.     main_window->show(argc,argv);
  414.   }
  415.   if (c && !read_file(c,0)) {
  416.     if (compile_only) {
  417.       fprintf(stderr,"%s : %s\n", c, strerror(errno));
  418.       exit(1);
  419.     }
  420.     fl_message("Can't read %s: %s", c, strerror(errno));
  421.   }
  422.   if (compile_only) {write_cb(0,0); exit(0);}
  423.   modflag = 0;
  424. #ifndef WIN32
  425.   signal(SIGINT,sigint);
  426. #endif
  427.   return Fl::run();
  428. }
  429.  
  430. //
  431. // End of "$Id: fluid.cxx,v 1.15.2.1 1999/04/18 23:43:42 mike Exp $".
  432. //
  433.